/************************************************************************************
**  
* @copyright (c) 2015-, Technology Co., LTD. All Right Reserved.
*
*************************************************************************************/
/**
* @file     duye_cap_netlayer_service.cpp
* @version     
* @brief      
* @author   
* @date     2013-01-09
* @note 
*
*  1. 2018-01-09  created this file
* 
*/
#include <duye_system.h>
#include <duye_logger.h>

#include <duye_cap_packet.h>
#include <duye_cap_filter_engine.h>
#include <duye_cap_netlayer_service.h>

static const int8* DUYE_LOG_PREFIX = "duye.cap.netlayer.service";

namespace duye {

NetLayerService::NetLayerService() : CapDataService("NetLayerService") {
	LinkLayerService::instance().addListener(this);
}

NetLayerService::~NetLayerService() {
	for (NetLayerListenerMap::iterator iter = m_listenerMap.begin(); iter != m_listenerMap.end(); ++iter) {
		delete iter->second;
	}

	m_listenerMap.clear();
}

bool NetLayerService::start() {
	startTask();
	return true;
}

bool NetLayerService::stop() {
	return true;
}

bool NetLayerService::run() {
	DUYE_INFO("NetLayerService Start");

	for (;;) {
		DUYE_INFO("NetLayerService Working");
		System::sleep(10);
	}

	DUYE_INFO("NetLayerService Exit");

	return true;
}

bool NetLayerService::addListener(DataServiceListener* listener, const FilterRule* filterRule) {
	NetLayerListener* netListener = dynamic_cast<NetLayerListener*>(listener);
	if (netListener == NULL) {
		return false;
	}
	
	FilterRule* copyFilterRule = NULL;
	if (filterRule == NULL) {
		m_listenerMap.insert(std::make_pair(netListener, copyFilterRule));
	} else {
		copyFilterRule = new FilterRule(*filterRule);
		m_listenerMap.insert(std::make_pair(netListener, copyFilterRule));
	}

	return true;
}

bool NetLayerService::delListener(DataServiceListener* listener) {
	m_listenerMap.erase(dynamic_cast<NetLayerListener*>(listener));
	return true;
}

int32 NetLayerService::onLinkLayerPacket(const PacketReference& pktRef) {
	if (pktRef.isNull()) {
		DUYE_ERROR("pktRef.isNull()");
		return -1;
	}

	DUYE_DEBUG("Protocol type(%d) is %s.\n", 
		pktRef->getNetLayerProto(), 
		Protocols::instance().getName(pktRef->getNetLayerProto()).c_str());

	for (NetLayerListenerMap::iterator iter = m_listenerMap.begin(); iter != m_listenerMap.end(); ++iter) {
		if (FilterEngine::instance().filterPkt(pktRef, iter->second)) {
			iter->first->onNetLayerPacket(pktRef);
		}
	}
	
	return 0;
}

}
